package com.zyx.juc.cf.my;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author Yaxi.Zhang
 * @since 2022/6/2 09:07
 * reference: https://baijiahao.baidu.com/s?id=1701173396839580698&wfr=spider&for=pc
 */
public class CompletableFutureAllOfDemo {
    public static void main(String[] args) {
        // 需求： 并行地下载 100 个网页。待下载完成之后，统计在 100 个网页中，含有某个单词的网页个数

        // allOf 的返回值是 CompletableFuture<Void>类型，这是因为 每个传入的 CompletableFuture 的返回值都可能不同
        // 所以组合的结果是 无法用某种类型来表示的，索性返回 Void 类型。
        List<String> webPages = Arrays.asList("taobao", "jd", "pdd", "dangdang", "amazon");
        List<CompletableFuture<String>> pageContentFutures = webPages
                .stream()
                .map(web -> CompletableFuture.supplyAsync(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "cf:" + web;
                }))
                .collect(Collectors.toList());
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(pageContentFutures.toArray(new CompletableFuture[0]));
        // 因为allof没有返回值，所以通过thenApply，给allFutures附上一个回调函数。
        // 在回调函数里面，以此调用每一个Future的join函数，获取到100个结果，存入List<String>

        // 附上回调函数，获取结果集
        CompletableFuture<List<String>> allPageContentsFuture = allFutures
                .thenApply(v -> pageContentFutures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList()));

        // 统计这100个网页中，含有某单词的网页的个数
        CompletableFuture<Long> countFuture = allPageContentsFuture.thenApply(pageContents -> pageContents
                .stream().filter(content -> content.contains("a")).count());

        // 输出结果
        System.out.println("一共有：" + countFuture.join() + "个网页包含单词[a]");
    }
}
